﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class AnimatorEx : ActorBaseExtension {

    protected bool _isPlaying;
    protected string _objectStateName;

    Queue<KeyValuePair<string, Action>> _actionQueue = new Queue<KeyValuePair<string, Action>>();

    private bool isPlaying;

    //动作播完之后默认回到的动作
    private string _defaultstate;  

    public AnimatorEx(GameObject go) : base(go)
    {

    }

    public override void OnUpdate()
    {
        base.OnUpdate();

        if (_isPlaying)
        {
            var stateInfo = animator.GetCurrentAnimatorStateInfo(0);

            if (stateInfo.normalizedTime >= 1f)
            {
                if (_actionQueue.Count > 0)
                {
                    var action = _actionQueue.Dequeue().Value;

                    if (action != null)
                    {
                        action();
                    }
                }

                _isPlaying = false;
            }
        }
    }

    public void CrossFade(string statename, float fixedtime,Action callback = null)
    {
        //注意：trigger触发一次执行一次，自动取消，但是如果上一次trigger未消耗完毕，
        //会缓存下一次trigger，所以不要多次激发，必要时使用ResetTrigger函数清除缓存的trigger
        animator.ResetTrigger("ToNext");
        animator.CrossFade(statename, fixedtime);

        MonoInstane.Instance.StartCoroutine(TimeUtility.DelayInvoke(fixedtime, () => _isPlaying = true));

        OnFinished(callback);

    }

    public AnimatorEx PlayDelay(string stateName,float delaytime, string sfxPath = null)
    {
        TimerManager.Instance.AddTimer(delaytime, () => {
            Play(stateName, sfxPath);
        });
        return this;
    }

    public AnimatorEx Play(string stateName, string sfxPath = null)
    {
        if (!string.IsNullOrEmpty(sfxPath))
        {
            AudioManager.Instance.PlaySound(sfxPath);
        }

        animator.Play(stateName, -1, 0f);

        // 为保证在下一帧运行的动画状态为Play()方法所触发的状态
        MonoInstane.Instance.StartCoroutine(TimeUtility.WaitForEndOfFrame(() => _isPlaying = true));

        _objectStateName = gameObject.name + ": " + stateName;
        return this;
    }

    public AnimatorEx SetTrigger(string triggerName, string sfxPath = null)
    {
        animator.SetTrigger(triggerName);

        // 为保证在下一次运行的动画状态为SetTrigger()方法所触发的状态
        // Unity默认动画间的过渡时间为 0.25s，如果有自行更改需注意
        MonoInstane.Instance.StartCoroutine(TimeUtility.DelayInvoke(0.25f, () => _isPlaying = true));

        if (!string.IsNullOrEmpty(sfxPath))
        {
            AudioManager.Instance.PlaySound(sfxPath);
        }

        _objectStateName = gameObject.name + ": " + triggerName;
        return this;
    }

    public void PlaySequenceDelay(string beginStateName, string voicePath,float delaytime, Action callback = null, bool removeAll = false)
    {
        TimerManager.Instance.AddTimer(delaytime, () => {
            PlaySequence(beginStateName, voicePath, callback, removeAll);
        });
    }

    public void PlaySequence(string beginStateName, string voicePath, Action callback = null, bool removeAll = false)
    {
        if (removeAll)
        {
            CleanQueue();
        }

        animator.ResetTrigger("ToNext");
        Play(beginStateName).OnFinished(() => {
            var duration = AudioManager.Instance.PlaySound(voicePath).Length;
            SetTrigger("ToNext");
            MonoInstane.Instance.StartCoroutine(TimeUtility.DelayInvoke(duration, () => SetTrigger("ToNext").OnFinished(callback)));
        });
    }

    public void PlaySequence(string beginStateName,float duration, Action callback = null, bool removeAll = false)
    {
        if (removeAll)
        {
            CleanQueue();
        }

        animator.ResetTrigger("ToNext");
        Play(beginStateName).OnFinished(() => {
            SetTrigger("ToNext");
            MonoInstane.Instance.StartCoroutine(TimeUtility.DelayInvoke(duration, () => SetTrigger("ToNext").OnFinished(callback)));
        });
    }

    private void CleanQueue()
    {
        for (int i = 0; i < _actionQueue.Count; i++)
        {
            Action act = _actionQueue.Dequeue().Value;
            act = null;
        }
        _actionQueue.Clear();
    }

    public void OnFinished(Action callback)
    {
        if (callback != null)
        {
            _actionQueue.Enqueue(new KeyValuePair<string, Action>(_objectStateName, callback));
        }
    }
}
